package com.quzhi.sys.controller.warehouseController;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quzhi.common.Result;
import com.quzhi.common.Utils;
import com.quzhi.sys.dto.InventoryDto;
import com.quzhi.sys.dto.ProductDto;
import com.quzhi.sys.entity.*;
import com.quzhi.sys.service.impl.GoodsTypeServiceImpl;
import com.quzhi.sys.service.impl.InventoryServiceImpl;
import com.quzhi.sys.service.impl.ProductServiceImpl;
import com.quzhi.sys.service.impl.WarehouseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 前端控制器 商品控制器
 * </p>
 *
 * @author Xibing
 * @since 2024-07-23
 */
@Slf4j
@RestController
@RequestMapping("/sys/product")
public class ProductController {

    @Autowired
    private ProductServiceImpl productService;

    @Autowired
    private GoodsTypeServiceImpl goodsTypeService;

    // 库存
    @Autowired
    private InventoryServiceImpl inventoryService;
    @Autowired
    private WarehouseServiceImpl warehouseService;


    @Autowired
    private RedisTemplate redisTemplate;


    @Value("${QuZhi.photoDownloadPath}")
    private String photoDownloadPath;

    // 获取商品
    @GetMapping("/list")
    public Result<?> getProductList(
            @RequestParam(value = "goodsName", required = false) String goodsName,
            @RequestParam(value = "warehouseName", required = false) String warehouseName,
            @RequestParam(value = "goodsTypeId", required = false) String goodsTypeId,
            @RequestParam(value = "pageNo") Long pageNo,
            @RequestParam(value = "pageSize") Long pageSize
    ) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasLength(goodsName), Product::getGoodsName, goodsName);
        wrapper.eq(StringUtils.hasLength(goodsTypeId), Product::getGoodsTypeId, goodsTypeId);

        Page<Product> infoPage = new Page<>(pageNo, pageSize);

        productService.page(infoPage, wrapper);

        List<Product> records = infoPage.getRecords();
        List<ProductDto> products = new ArrayList<>();

        // 获取库存，获取库存对应的仓库
        for (Product record : records) {
            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(record, productDto);

            // 更具订单ID查询序列号表
            GoodsType byId = goodsTypeService.getById(record.getGoodsTypeId());
            if (byId != null) {
                productDto.setGoodsType(byId.getType());
            }

            // 获取商品对应的所有库存
            LambdaQueryWrapper<Inventory> inventoryWrapper = new LambdaQueryWrapper<>();
            inventoryWrapper.eq(Inventory::getProductId, productDto.getId());
            List<Inventory> list = inventoryService.list(inventoryWrapper);
            List<InventoryDto> inventoryDtos = new ArrayList<>();

            LambdaQueryWrapper<Warehouse> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(StringUtils.hasLength(warehouseName), Warehouse::getWarehouseName, warehouseName);
            List<Warehouse> warehouseList = warehouseService.list(lambdaQueryWrapper);
            if (list != null) {
                // 获取对应的仓库名称
                for (Inventory inventory : list) {
                    InventoryDto inventoryDto = new InventoryDto();
                    BeanUtils.copyProperties(inventory, inventoryDto);
                    for (Warehouse warehouse : warehouseList) {
                        if (warehouse.getId().equals(inventory.getWarehouseId())) {
                            inventoryDto.setWarehouseName(warehouse.getWarehouseName());
                            inventoryDtos.add(inventoryDto);
                            break;
                        }
                    }
                }
                productDto.setInventoryDto(inventoryDtos);
            }
            products.add(productDto);
        }
        Map<String, Object> data = new HashMap<>();
        data.put("rows", products);
        data.put("total", infoPage.getTotal());
        return Result.success(data);
    }

    @GetMapping("/select")
    public Result<?> getAllProductNameAndId() {
        List<Product> list = productService.list();

        List<Map<String, String>> reList = new ArrayList<>();

        for (Product product : list) {
            Map<String, String> house = new HashMap<>();
            house.put("id", product.getId());
            house.put("goodsName", product.getGoodsName());
            reList.add(house);
        }
        return Result.success(reList);
    }

    @GetMapping("/{id}")
    public Result<?> getById(@PathVariable("id") String id) {
        Product product = productService.getById(id);
        if (product != null) {
            GoodsType type = new GoodsType();
            if (product.getGoodsTypeId() != null) {
                type = goodsTypeService.getById(product.getGoodsTypeId());
            }

            ProductDto productDto = new ProductDto();
            BeanUtils.copyProperties(product, productDto);
            if (type == null) {
                productDto.setGoodsType(null);

            } else {
                productDto.setGoodsType(type.getType());

            }
            return Result.success(productDto);
        }
        return Result.success(20002, "不存在");
    }

    // 调拨库存，根据调出仓库获取库存商品,

    /**
     * 可更具序列号或者商品名称获取对应的商品
     *
     * @param warehouseName
     * @param goodsName
     * @param serialNumber
     * @return 返回，商品名称，所在仓库 库存数量
     */
    @GetMapping("/getProductByWarehouse")
    public Result<?> getByWarehouseName(
            @RequestParam(value = "warehouseId") String warehouseId,
            @RequestParam(value = "goodsName", required = false) String goodsName,
            @RequestParam(value = "serialNumber", required = false) String serialNumber,
            @RequestParam(value = "pageNo") Long pageNo,
            @RequestParam(value = "pageSize") Long pageSize

    ) {

        // 获取所有商品
        Page<Product> infoPage = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<Product> productLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productLambdaQueryWrapper.like(StringUtils.hasLength(goodsName), Product::getGoodsName, goodsName);

        // 获取所有商品
        productService.page(infoPage, productLambdaQueryWrapper);

        // 获取商品对应的库存,需要更具仓库查询
        // 先获取到扫所有仓库，在获取到仓库名称对应的ID
        LambdaQueryWrapper<Warehouse> warehouseLambdaQueryWrapper = new LambdaQueryWrapper<>();
        warehouseLambdaQueryWrapper.eq(StringUtils.hasLength(warehouseId), Warehouse::getId, warehouseId);
        Warehouse warehouse = warehouseService.getOne(warehouseLambdaQueryWrapper); // 获取到需要的仓库
        if (warehouse == null) return Result.fail(20002, "仓库不存在");
        // 获取库存
        LambdaQueryWrapper<Inventory> inventoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        inventoryLambdaQueryWrapper.eq(Inventory::getWarehouseId, warehouse.getId());
        // 仓库中所有的序列号，还没有区分序列号对应的商品
        List<Inventory> inventoryList = inventoryService.list(inventoryLambdaQueryWrapper);

        // 遍历所有的商品，把序列号对应的商品添加进去
        List<Product> records = infoPage.getRecords();

        // 商品集合，商品和对应库存的序列号
        List<ProductDto> productDtoList = Utils.getProductDto(records, inventoryList);


        Map<String, Object> data = new HashMap<>();
        // 如果序列号参数不为空，则根据序列号查询商品
        if (serialNumber != null && !serialNumber.equals("")) {
            for (ProductDto productDto : productDtoList) {
                for (InventoryDto inventoryDto : productDto.getInventoryDto()) {
                    // 暂时使用完全匹配的方法
                    if (inventoryDto.getSerialNumber().equals(serialNumber)) {
                        List<Object> rows = new ArrayList<>();
                        Map<String, Object> productData = new HashMap<>();
                        // 返回数据
                        productData.put("id", productDto.getId());
                        productData.put("goodsName", productDto.getGoodsName());
                        productData.put("InventoryNum", productDto.getInventoryDto().size());
                        productData.put("transferGoods", new ArrayList<>());
                        rows.add(productData);
                        data.put("rows",rows);

                        data.put("total", 1);
                        return Result.success(data);
                    }
                }
            }
            List<Object> rows = new ArrayList<>();
            Map<String, Object> productData = new HashMap<>();
            rows.add(productData);
            data.put("rows",rows);

            data.put("total", 0);
            return Result.success(data);
        }

        // 只返回有库存的商品
        List<Object> rows = new ArrayList<>();

        // 仓库中空商品的数量
        for (ProductDto productDto : productDtoList) {
            if(productDto.getInventoryDto().size() > 0){
                Map<String, Object> productData = new HashMap<>();
                productData.put("id", productDto.getId());
                productData.put("goodsName", productDto.getGoodsName());
                productData.put("InventoryNum", productDto.getInventoryDto().size());
                productData.put("transferGoods", new ArrayList<>());
                rows.add(productData);
            }
        }



        data.put("rows", rows);
        data.put("total", infoPage.getTotal());

        return Result.success(data);
    }

    // 添加商品
    @PostMapping
    public Result<?> addProduct(@RequestBody ProductDto productDto) {

        // 添加商品
        Product product = new Product();
        product.setId(UUID.randomUUID().toString());
        product.setGoodsName(productDto.getGoodsName());
        product.setRemark(productDto.getRemark());
        product.setPhotoName(photoDownloadPath + productDto.getPhotoName());
        product.setGoodsTypeId(productDto.getGoodsTypeId());
        product.setCreateTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());

        productService.save(product);
        return Result.success();
    }

    @PutMapping
    public Result<?> updateById(@RequestBody ProductDto productDto) {
        log.error(productDto.getPhotoName());
        Product product = new Product();
        BeanUtils.copyProperties(productDto, product);
        // 获取分类
        if (productDto.getGoodsType() != null) {
            LambdaQueryWrapper<GoodsType> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(GoodsType::getType, productDto.getGoodsType());
            GoodsType one = goodsTypeService.getOne(wrapper);
            if (one != null) {
                product.setGoodsTypeId(one.getId());
            }
            if (productDto.getPhotoName() != null) {
                product.setPhotoName(photoDownloadPath + productDto.getPhotoName());
            } else {
                product.setPhotoName("");
            }
        }

        productService.updateById(product);

        return Result.success("更新成功");
    }

    @DeleteMapping("/{id}")
    public Result<?> deleteById(@PathVariable("id") String id, @RequestBody String qz_token) {
        // 查询当前用户的权限是否可以删除仓库
        Object obj = redisTemplate.opsForValue().get(qz_token);
        if (obj != null) {
            // 将数据转成json数据
            User loginUser = JSON.parseObject(JSON.toJSONString(obj), User.class);
            // 删除仓库
            String role = loginUser.getRole();
            if (role.equals("admin")) {
                // 权限足够可以删除
                productService.removeById(id);

                // 删除商品对应的序列号
                LambdaQueryWrapper<Inventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(Inventory::getProductId, id);
                inventoryService.remove(lambdaQueryWrapper);

                return Result.success("删除成功");
            } else {
                return Result.fail(20002, "你没有权限执行此操作");
            }
        } else {
            return Result.fail(20002, "删除失败");
        }

    }
}
